﻿<?php
	class serviceFactory{
		public static function getService($service){
			return new TransactionDelegator($service);
		}
	};
	
	class TransactionDelegator { 
		private $service; 
		
		function __construct($service) { 
			$this->service = $service; 
		} 
		
		function __call($name, $args) { 
			
			$result;
			$r = new ReflectionClass($this->service); 
			if ($method = $r->getMethod($name)) { 
				if ($method->isPublic() && !$method->isAbstract()) { 
					$withTrans = (boolean)(strpos($name,"_tr_") === 0);
					$a = array();
					try{
						$withTrans && $this->startTransaction($a);
						$result = $method->invoke($this->service, $args); 
					}catch(Exception $e){
						echo $e;
						throw $e;
					}
					finally {
						//$withTrans && this->endTransaction($a);
					}
				} 
			} 						
			return $result;
		} 
		
		
		function startTransaction($array){
			echo "<br>开启事务<br>";
			function transErrorHandler($errno, $errstr){ 
				echo "<b>Error:</b> [$errno] $errstr<br />";
				$array[0] = true;
				throw new Exception($errstr);
			}
			$this->curErrorHandler = set_error_handler("transErrorHandler");	
		}
		
		function endTransaction($array){
			echo "<br>结束事务:<br>";
			
			//$array[0] ? this->rollback() : this->commit();	
			set_error_handler($this->curErrorHandler ? $this->curErrorHandler : "defaultHandler");
		}
		
		function commit(){
			echo "<br>提交事务<br>";
		}
		
		function rollback(){
			echo "<br>回滚事务<br>";
		}
		
		function defaultHandler($errno, $errstr){
			echo "<b>Error:</b> [$errno] $errstr<br />";
		}
		
		
	} 
	
	class ClassOne { 
		function _tr_callClassOne() { 
			try{
				print 1/0;
			}catch(Exception $e){
				echo "异常被捕获";
			}		
		} 
		function callClassOne() { 
			
			$this->_tr_callClassOne(); 
			
		} 
	}
	
	function oldHandler($errno, $errstr)
	{ 
		 echo "<b>Error:</b> [$errno] $errstr<br />";
	}
	
	//set_error_handler("oldHandler");
	
	$service1 = serviceFactory ::getService(new ClassOne());
	
	try{$service1->callClassOne();
		$service1->_tr_callClassOne();
	}catch(Exception $e){
		
	}
?>